package com.carl.lambda.streamAPI.lambda01;


import com.carl.lambda.simpleLambda.lambda1.Employee;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/*
 * 一、Stream API 的操作步骤：
 *
 * 1. 创建 Stream
 *
 * 2. 中间操作
 *
 * 3. 终止操作(终端操作)
 */
public class TestStreamAPI4 {


    List<Employee> employees = Arrays.asList(
            new Employee("张三",18,99.99, Employee.Status.BUSY),
            new Employee("李四",28,999.99, Employee.Status.FREE),
            new Employee("王五",32,9999.99, Employee.Status.VOCATION),
            new Employee("赵六",48,9999.99,Employee.Status.BUSY),
            new Employee("钱七",58,9999.99,Employee.Status.VOCATION),
            new Employee("钱七",58,9999.99,Employee.Status.FREE),
            new Employee("钱七",58,9999.99, Employee.Status.BUSY)
    );
    //3. 终止操作
	/*
		归约
		reduce(T identity, BinaryOperator) / reduce(BinaryOperator) ——可以将流中元素反复结合起来，得到一个值。
	 */
    @Test
    public void test01(){
        List<Integer> list  = Arrays.asList(1,2,3,5,6,7,8,9,10);
        Optional<Integer> optionalI = list.stream().reduce(Integer::sum);
        Integer integer = optionalI.get();
        System.out.println(integer);
    }

    @Test
    public void test02(){
        Double v = employees.stream().map(Employee::getSalary)
                .reduce(Double::sum).get();
        System.out.println(v);
    }

    /*
      4.收集
      collect——将流转换为其他形式。接收一个 Collector接口的实现，用于给Stream中元素做汇总的方法
     */

    @Test
    public void test03(){
         employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toList()).forEach(System.out::println);
        System.out.println("-------------------");
         //去重
         employees.stream()
                 .map(Employee::getName)
                 .collect(Collectors.toSet()).forEach(System.out::println);
        System.out.println("-------------------");
        employees.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(HashSet::new)).forEach(System.out::println);
    }

    @Test
    public void test04(){
        //总条数
        Long collect = employees.stream().collect(Collectors.counting());
        System.out.println(collect);
        System.out.println("-------------------");
        //平均值
        Double collect1 = employees.stream().collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println(collect1);
        System.out.println("-------------------");
        //总和
        Double collect2 = employees.stream().collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println(collect2);
        System.out.println("-------------------");
        //最大值对象
        Optional<Employee> collect3 = employees.stream().collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
        System.out.println(collect3.get());
        //最小值具体值
        Double v = employees.stream()
                .map(Employee::getSalary)
                .collect(Collectors.minBy(Double::compare)).get();
        System.out.println(v);
    }

    //按照状态进行分组
    @Test
    public void test05(){
        Map<Employee.Status, List<Employee>> collect = employees.stream()
                .collect(Collectors.groupingBy(Employee::getStatus));
        System.out.println(collect);
    }

    //多级分组 先按状态分再按年龄段分
    @Test
    public void test06(){
        Map<Employee.Status, Map<String, List<Employee>>> collect = employees.stream()
                .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(e -> {
            if (e.getAge() <= 35) {
                return "青年";
            } else if (e.getAge() < 50) {
                return "中年";
            } else {
                return "老年";
            }
        })));
        System.out.println(collect);
        //获取状态是busy中青年的对象
        employees.stream().collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(e -> {
            if (e.getAge() <= 35) {
                return "青年";
            } else if (e.getAge() < 50) {
                return "中年";
            } else {
                return "老年";
            }
        }))).get(Employee.Status.BUSY).get("青年").forEach(System.out::println);

    }

    //分片
    @Test
    public void test07(){
        Map<Boolean, List<Employee>> collect = employees.stream().collect(Collectors.partitioningBy(e -> e.getSalary() > 8000));
        System.out.println(collect);


        DoubleSummaryStatistics collect1 = employees.stream().collect(Collectors.summarizingDouble(Employee::getSalary));
        System.out.println(collect1.getMax());
        System.out.println(collect1.getCount());
    }


    @Test
    public void test08(){
        String collect = employees.stream()
                .map(Employee::getName)
                .collect(Collectors.joining(",", "==", "=="));
        System.out.println(collect);
    }

























}
